home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xmcd-1.4 / libdi.d / os_irix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-10  |  6.0 KB  |  284 lines

  1. /*
  2.  *   libdi - CD Audio Player Device Interface Library
  3.  *
  4.  *   Copyright (C) 1995  Ti Kan
  5.  *   E-mail: ti@amb.org
  6.  *
  7.  *   This program is free software; you can redistribute it and/or modify
  8.  *   it under the terms of the GNU General Public License as published by
  9.  *   the Free Software Foundation; either version 2 of the License, or
  10.  *   (at your option) any later version.
  11.  *
  12.  *   This program is distributed in the hope that it will be useful,
  13.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *   GNU General Public License for more details.
  16.  *
  17.  *   You should have received a copy of the GNU General Public License
  18.  *   along with this program; if not, write to the Free Software
  19.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  *
  21.  *   This software fragment contains code that interfaces the CD player
  22.  *   application to the SGI IRIX operating system.  The names "SGI" and
  23.  *   "IRIX" are used here for identification purposes only.  This software
  24.  *   and its author are not affiliated with Silicon Graphics, Inc.
  25.  *
  26.  */
  27. #ifndef LINT
  28. static char *_os_irix_c_ident_ = "@(#)os_irix.c    5.6 94/12/28";
  29. #endif
  30.  
  31. #include "common.d/appenv.h"
  32. #include "common.d/util.h"
  33. #include "libdi.d/libdi.h"
  34. #include "libdi.d/scsipt.h"
  35.  
  36. #if defined(sgi) && defined(DI_SCSIPT) && !defined(DEMO_ONLY)
  37.  
  38. extern appdata_t    app_data;
  39. extern bool_t        scsipt_notrom_error;
  40. extern FILE        *errfp;
  41.  
  42. STATIC int        pthru_fd = -1;    /* Passthrough device file desc */
  43. STATIC req_sense_data_t    sense_data;    /* Request sense data buffer */
  44.  
  45.  
  46. /*
  47.  * pthru_send
  48.  *    Build SCSI CDB and send command to the device.
  49.  *
  50.  * Args:
  51.  *    opcode - SCSI command opcode
  52.  *    addr - The "address" portion of the SCSI CDB
  53.  *    buf - Pointer to data buffer
  54.  *    size - Number of bytes to transfer
  55.  *    rsvd - The "reserved" portion of the SCSI CDB
  56.  *    length - The "length" portion of the SCSI CDB
  57.  *    param - The "param" portion of the SCSI CDB
  58.  *    control - The "control" portion of the SCSI CDB
  59.  *    rw - Data transfer direction flag (READ_OP or WRITE_OP)
  60.  *    prnerr - Whether an error message should be displayed
  61.  *         when a command fails
  62.  *
  63.  * Return:
  64.  *    TRUE - command completed successfully
  65.  *    FALSE - command failed
  66.  */
  67. bool_t
  68. pthru_send(
  69.     byte_t        opcode,
  70.     word32_t    addr,
  71.     byte_t        *buf,
  72.     word32_t    size,
  73.     byte_t        rsvd,
  74.     word32_t    length,
  75.     byte_t        param,
  76.     byte_t        control,
  77.     byte_t        rw,
  78.     bool_t        prnerr
  79. )
  80. {
  81.     struct dsreq    dsreq;
  82.     byte_t        cdb[12];
  83.  
  84.     if (pthru_fd < 0 || scsipt_notrom_error)
  85.         return FALSE;
  86.  
  87.     memset(cdb, 0, sizeof(cdb));
  88.     memset(&dsreq, 0, sizeof(dsreq));
  89.     memset(&sense_data, 0, sizeof(sense_data));
  90.  
  91.     /* set up SCSI CDB */
  92.     switch (opcode & 0xf0) {
  93.     case 0xa0:
  94.     case 0xe0:
  95.         /* 12-byte commands */
  96.         cdb[0] = opcode;
  97.         cdb[1] = param;
  98.         cdb[2] = (addr >> 24) & 0xff;
  99.         cdb[3] = (addr >> 16) & 0xff;
  100.         cdb[4] = (addr >> 8) & 0xff;
  101.         cdb[5] = (addr & 0xff);
  102.         cdb[6] = (length >> 24) & 0xff;
  103.         cdb[7] = (length >> 16) & 0xff;
  104.         cdb[8] = (length >> 8) & 0xff;
  105.         cdb[9] = length & 0xff;
  106.         cdb[10] = rsvd;
  107.         cdb[11] = control;
  108.  
  109.         dsreq.ds_cmdlen = 12;
  110.         break;
  111.  
  112.     case 0xc0:
  113.     case 0xd0:
  114.     case 0x20:
  115.     case 0x30:
  116.     case 0x40:
  117.         /* 10-byte commands */
  118.         cdb[0] = opcode;
  119.         cdb[1] = param;
  120.         cdb[2] = (addr >> 24) & 0xff;
  121.         cdb[3] = (addr >> 16) & 0xff;
  122.         cdb[4] = (addr >> 8) & 0xff;
  123.         cdb[5] = addr & 0xff;
  124.         cdb[6] = rsvd;
  125.         cdb[7] = (length >> 8) & 0xff;
  126.         cdb[8] = length & 0xff;
  127.         cdb[9] = control;
  128.  
  129.         dsreq.ds_cmdlen = 10;
  130.         break;
  131.  
  132.     case 0x00:
  133.     case 0x10:
  134.         /* 6-byte commands */
  135.         cdb[0] = opcode;
  136.         cdb[1] = param;
  137.         cdb[2] = (addr >> 8) & 0xff;
  138.         cdb[3] = addr & 0xff;
  139.         cdb[4] = length & 0xff;
  140.         cdb[5] = control;
  141.  
  142.         dsreq.ds_cmdlen = 6;
  143.         break;
  144.  
  145.     default:
  146.         if (app_data.scsierr_msg && prnerr)
  147.             fprintf(errfp, "0x%02x: Unknown SCSI opcode\n",
  148.                 opcode);
  149.         return FALSE;
  150.     }
  151.  
  152.     DBGDUMP("SCSI CDB bytes", cdb, dsreq.ds_cmdlen);
  153.  
  154.     /* Set up dsreq */
  155.     dsreq.ds_cmdbuf = (caddr_t) cdb;
  156.  
  157.     if (buf != NULL && size != 0) {
  158.         dsreq.ds_flags |= (rw == READ_OP) ? DSRQ_READ : DSRQ_WRITE;
  159.         dsreq.ds_databuf = (caddr_t) buf;
  160.         dsreq.ds_datalen = (ulong) size;
  161.     }
  162.  
  163.     dsreq.ds_flags |= DSRQ_SENSE;
  164.     dsreq.ds_sensebuf = (caddr_t) &sense_data;
  165.     dsreq.ds_senselen = (ulong) SZ_RSENSE;
  166.  
  167.     dsreq.ds_time = 5000;    /* Allow 5 seconds */
  168.  
  169.     /* Send the command down via the "pass-through" interface */
  170.     if (ioctl(pthru_fd, DS_ENTER, &dsreq) < 0) {
  171.         if (app_data.scsierr_msg && prnerr) 
  172.             perror("DS_ENTER ioctl failed");
  173.         return FALSE;
  174.     }
  175.  
  176.     if (dsreq.ds_ret != 0) {
  177.         if (app_data.scsierr_msg && prnerr) {
  178.             fprintf(errfp,
  179.                 "CD audio: %s %s:\n%s=0x%x %s=0x%x %s=0x%x",
  180.                 "SCSI command error on",
  181.                 app_data.device,
  182.                 "Opcode",
  183.                 opcode,
  184.                 "Ret",
  185.                 dsreq.ds_ret,
  186.                 "Status",
  187.                 dsreq.ds_status);
  188.  
  189.             if (sense_data.valid == 0)
  190.                 fprintf(errfp, "\n");
  191.             else {
  192.                 fprintf(errfp,
  193.                     " Key=0x%x Code=0x%x Qual=0x%x\n",
  194.                     sense_data.key,
  195.                     sense_data.code,
  196.                     sense_data.qual);
  197.             }
  198.         }
  199.  
  200.         return FALSE;
  201.     }
  202.     
  203.     return TRUE;
  204. }
  205.  
  206.  
  207. /*
  208.  * pthru_open
  209.  *    Open SCSI pass-through device
  210.  *
  211.  * Args:
  212.  *    path - device path name string
  213.  *
  214.  * Return:
  215.  *    TRUE - open successful
  216.  *    FALSE - open failed
  217.  */
  218. bool_t
  219. pthru_open(char *path)
  220. {
  221.     struct stat    stbuf;
  222.     char        errstr[ERR_BUF_SZ];
  223.  
  224.     /* Check for validity of device node */
  225.     if (stat(path, &stbuf) < 0) {
  226.         sprintf(errstr, app_data.str_staterr, path);
  227.         cd_fatal_popup(app_data.str_fatal, errstr);
  228.         return FALSE;
  229.     }
  230.  
  231.     if (!S_ISCHR(stbuf.st_mode)) {
  232.         sprintf(errstr, app_data.str_noderr, path);
  233.         cd_fatal_popup(app_data.str_fatal, errstr);
  234.         return FALSE;
  235.     }
  236.  
  237.     if ((pthru_fd = open(path, O_RDONLY)) < 0) {
  238.         DBGPRN(errfp, "Cannot open %s: errno=%d\n", path, errno);
  239.         return FALSE;
  240.     }
  241.  
  242.     return TRUE;
  243. }
  244.  
  245.  
  246. /*
  247.  * pthru_close
  248.  *    Close SCSI pass-through device
  249.  *
  250.  * Args:
  251.  *    Nothing.
  252.  *
  253.  * Return:
  254.  *    Nothing.
  255.  */
  256. void
  257. pthru_close(void)
  258. {
  259.     if (pthru_fd >= 0) {
  260.         close(pthru_fd);
  261.         pthru_fd = -1;
  262.     }
  263. }
  264.  
  265.  
  266. /*
  267.  * pthru_vers
  268.  *    Return OS Interface Module version string
  269.  *
  270.  * Args:
  271.  *    Nothing.
  272.  *
  273.  * Return:
  274.  *    Module version text string.
  275.  */
  276. char *
  277. pthru_vers(void)
  278. {
  279.     return ("OS Interface module (for SGI IRIX)\n");
  280. }
  281.  
  282. #endif    /* sgi DI_SCSIPT DEMO_ONLY */
  283.  
  284.